package com.xuesinuo.ots.config.pignoo;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.xuesinuo.ots.Application;
import com.xuesinuo.ots.entity.Role;
import com.xuesinuo.ots.entity.User;
import com.xuesinuo.pignoo.autodatabase.EntityScanConfig;
import com.xuesinuo.pignoo.autodatabase.EntityScaner;
import com.xuesinuo.pignoo.core.Pignoo;
import com.xuesinuo.pignoo.core.PignooConfig;
import com.xuesinuo.pignoo.core.PignooSorter.SMode;
import com.xuesinuo.pignoo.spring.implement.SpringPignoo;

@Configuration
public class PignooConfiguration {

    public static volatile EntityScanConfig.BuildMode PIGNOO_SCAN_MODE = EntityScanConfig.BuildMode.CAREFULLY;

    @Bean
    PignooConfig pignooConfig() {
        PignooConfig pignooConfig = new PignooConfig();
        return pignooConfig;
    }

    @Bean
    Pignoo pignoo(@Autowired DataSource dataSource, @Autowired PignooConfig pignooConfig) {
        return new SpringPignoo(dataSource, pignooConfig);
    }

    @Bean
    EntityScaner entityScaner(@Autowired DataSource dataSource, @Autowired PignooConfig pignooConfig, @Autowired Pignoo pignoo) {
        EntityScanConfig entityScanConfig = new EntityScanConfig();
        entityScanConfig.setClassesForScanPackage(new Class<?>[] { Application.class });
        entityScanConfig.setBuildMode(PIGNOO_SCAN_MODE);
        entityScanConfig.setBreakRunning(false);
        entityScanConfig.setStrictColumnType(true);
        EntityScaner scanner = new EntityScaner(dataSource, pignooConfig, entityScanConfig);
        scanner.scan();
        initDatabase(pignoo);
        return scanner;
    }

    private void initDatabase(Pignoo pignoo) {
        Role role = pignoo.reader(Role.class).sort(Role::getId, SMode.MIN_FIRST).getFirst();
        if (role == null || role.getId() != 1L) {
            role = new Role();
            role.setId(1L);
            role.setName("Super Administrator");
            role.setMenuJson("[]");
            role.setAuthJson("[]");
            pignoo.writer(Role.class).add(role);
        }
        User user = pignoo.reader(User.class).sort(User::getId, SMode.MIN_FIRST).getFirst();
        if (user == null || user.getId() != 1L) {
            user = pignoo.reader(User.class).filter(User::getUsername, "==", "admin").getAny();
            if (user != null) {
                throw new RuntimeException("username 'admin' user already exists at id=" + user.getId());
            }
            user = new User();
            user.setId(1L);
            user.setCode("A001");
            user.setNick("admin");
            user.setPhone("");
            user.setUsername("admin");
            user.setPassword("$2a$12$Qh/kFeLD5HyTbYmkZC/ZQ.hFUPiHpWxYpjQXra5d.TXnBQ5IOriOi"); // 123456
            user.setCreateDatetime(System.currentTimeMillis());
            user.setHasUsing(true);
            user.setAdmin(true);
            user.setRoleId(1L);
            pignoo.writer(User.class).add(user);
        }
    }
}
